import os,sys
from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps
from conan.tools.system import package_manager
import platform
from datetime import datetime
import time

manager_mapping = {"Apt": ["Linux", "ubuntu", "kylin", "debian", "raspbian", "linuxmint", 'astra', 'elbrus', 'altlinux', 'pop'],
                    "Apk": ["alpine"],
                    "Yum": ["pidora", "scientific", "xenserver", "amazon", "oracle", "amzn",
                            "almalinux", "rocky"],
                    "Dnf": ["fedora", "rhel", "centos", "mageia", "nobara"],
                    "Brew": ["Darwin"],
                    "PacMan": ["arch", "manjaro", "msys2", "endeavouros"],
                    "Chocolatey": ["Windows"],
                    "Zypper": ["opensuse", "sles"],
                    "Pkg": ["freebsd"],
                    "Pkgutil": ["Solaris"]
                   }

class helloRecipe(ConanFile):
    name = "QTBuild"
    version = "5.14.2-ubuntu"
    package_type = "build-scripts"

    # 个人信息
    license = "MIT"
    author = "<OSmile> <whghcyx@outlook.com>"
    url = "https://whg555.github.io"
    description = "readme description"
    topics = ("<Put some tag here>", "<here>", "<and here>")

    # 安装包
    packages = {
        "ubuntu" :  {
            "default" : ["qtbase5-dev", "build-essential", "perl", "python3", "python", "git", "ninja-build", "cmake",
                   # llvm
                   "llvm",
                   # Libxcb
                   "^libxcb.*-dev", "libx11-xcb-dev", "libgl1-mesa-dev", "libglu1-mesa-dev", "libxrender-dev",
                   "libxi-dev", "libxkbcommon-dev", "libxkbcommon-x11-dev",
                   # Wayland Client
                   "libwayland-dev",
                   # WebKit
                   "flex", "bison", "gperf", "libicu-dev", "libxslt-dev", "ruby",
                   # WebEngine
                   "libxcursor-dev", "libxcomposite-dev", "libxdamage-dev", "libxrandr-dev", "libxtst-dev",
                   "libxss-dev", "libdbus-1-dev", "libevent-dev", "libfontconfig1-dev",
                   "libcap-dev", "libpulse-dev", "libudev-dev", "libpci-dev", "libnss3-dev",
                   # Multimedia
                   "libasound2-dev", "libegl1-mesa-dev", "gperf", "bison", "nodejs", "libdrm-dev", "libasound2-dev",
                   "libgstreamer1.0-dev", "libgstreamer-plugins-base1.0-dev", "libgstreamer-plugins-good1.0-dev",
                   "libgstreamer-plugins-bad1.0-dev",
                   # 修复错误
                   "clang", "libclang-dev", "libclang-perl", "zstd", "libkrb5-dev", "libpoppler-cpp0v5",
                   "libgssapi-krb5-2", "", "freetds-dev", "libsdl2-dev", "gawk", "wayland-protocols",
                   "libbluetooth-dev", "libopenal-dev", "libflite1", "flite1-dev", "libspeechd-dev", "libdrm*",
                   "libassimp-dev", "libdlm-dev", "libdlm3", "libzstd-dev", "libvpx-dev", "libwebp-dev", "ffmpeg",
                   "libinput-dev", "minizip", "libjsoncpp-dev", "libprotobuf-dev", "liblcms2-dev", "libharfbuzz-dev",
                   "libopus-dev", "libicu-dev", "libre2-dev", "libsnappy-dev", "libminizip-dev", "libprotobuf-c-dev",
                   "protobuf-compiler", "protobuf-compiler-grpc", "libmng-dev", "libmd4c-dev", "libmd4c0", "libssl-dev",
                   "libatspi2.0-dev", "libgnatcoll-syslog2", "libgnatcoll-syslog2-dev", "libpoppler-cpp-dev"],
            "18": ["qtbase5-dev", "build-essential", "perl", "python3", "python", "git", "ninja-build", "cmake",
                   # llvm
                   "llvm",
                   # Libxcb
                   "^libxcb.*-dev", "libx11-xcb-dev", "libgl1-mesa-dev", "libglu1-mesa-dev", "libxrender-dev",
                   "libxi-dev", "libxkbcommon-dev", "libxkbcommon-x11-dev",
                   # Wayland Client
                   "libwayland-dev",
                   # WebKit
                   "flex", "bison", "gperf", "libicu-dev", "libxslt-dev", "ruby",
                   # WebEngine
                   "libxcursor-dev", "libxcomposite-dev", "libxdamage-dev", "libxrandr-dev", "libxtst-dev",
                   "libxss-dev", "libdbus-1-dev", "libevent-dev", "libfontconfig1-dev",
                   "libcap-dev", "libpulse-dev", "libudev-dev", "libpci-dev", "libnss3-dev",
                   # Multimedia
                   "libasound2-dev", "libegl1-mesa-dev", "gperf", "bison", "nodejs", "libdrm-dev", "libasound2-dev",
                   "libgstreamer1.0-dev", "libgstreamer-plugins-base1.0-dev", "libgstreamer-plugins-good1.0-dev",
                   "libgstreamer-plugins-bad1.0-dev",
                   # 修复错误
                   "clang", "libclang-dev", "libclang-perl", "zstd", "libkrb5-dev", "libpoppler-cpp0v5",
                   "libgssapi-krb5-2", "", "freetds-dev", "libsdl2-dev", "gawk", "wayland-protocols",
                   "libbluetooth-dev", "libopenal-dev", "libflite1", "flite1-dev", "libspeechd-dev", "libdrm*",
                   "libassimp-dev", "libdlm-dev", "libdlm3", "libzstd-dev", "libvpx-dev", "libwebp-dev", "ffmpeg",
                   "libinput-dev", "minizip", "libjsoncpp-dev", "libprotobuf-dev", "liblcms2-dev", "libharfbuzz-dev",
                   "libopus-dev", "libicu-dev", "libre2-dev", "libsnappy-dev", "libminizip-dev", "libprotobuf-c-dev",
                   "protobuf-compiler", "protobuf-compiler-grpc", "libmng-dev", "libmd4c-dev", "libmd4c0", "libssl-dev",
                   "libatspi2.0-dev", "libgnatcoll-syslog2", "libgnatcoll-syslog2-dev", "libpoppler-cpp-dev"],
            # 测试通过
            "20": ["qtbase5-dev", "build-essential", "perl", "python3", "python", "git", "ninja-build", "cmake",
                   # llvm
                   "llvm",
                   # Libxcb
                   "^libxcb.*-dev", "libx11-xcb-dev", "libgl1-mesa-dev", "libglu1-mesa-dev", "libxrender-dev",
                   "libxi-dev", "libxkbcommon-dev", "libxkbcommon-x11-dev",
                   # Wayland Client
                   "libwayland-dev",
                   # WebKit
                   "flex", "bison", "gperf", "libicu-dev", "libxslt-dev", "ruby",
                   # WebEngine
                   "libxcursor-dev", "libxcomposite-dev", "libxdamage-dev", "libxrandr-dev", "libxtst-dev",
                   "libxss-dev", "libdbus-1-dev", "libevent-dev", "libfontconfig1-dev",
                   "libcap-dev", "libpulse-dev", "libudev-dev", "libpci-dev", "libnss3-dev",
                   # Multimedia
                   "libasound2-dev", "libegl1-mesa-dev", "gperf", "bison", "nodejs", "libdrm-dev", "libasound2-dev",
                   "libgstreamer1.0-dev", "libgstreamer-plugins-base1.0-dev", "libgstreamer-plugins-good1.0-dev",
                   "libgstreamer-plugins-bad1.0-dev",
                   # 修复错误
                   "clang", "libclang-dev", "libclang-perl", "zstd", "libkrb5-dev", "libpoppler-cpp0v5",
                   "libgssapi-krb5-2", "", "freetds-dev", "libsdl2-dev", "gawk", "wayland-protocols",
                   "libbluetooth-dev", "libopenal-dev", "libflite1", "flite1-dev", "libspeechd-dev", "libdrm*",
                   "libassimp-dev", "libdlm-dev", "libdlm3", "libzstd-dev", "libvpx-dev", "libwebp-dev", "ffmpeg",
                   "libinput-dev", "minizip", "libjsoncpp-dev", "libprotobuf-dev", "liblcms2-dev", "libharfbuzz-dev",
                   "libopus-dev", "libicu-dev", "libre2-dev", "libsnappy-dev", "libminizip-dev", "libprotobuf-c-dev",
                   "protobuf-compiler", "protobuf-compiler-grpc", "libmng-dev", "libmd4c-dev", "libmd4c0", "libssl-dev",
                   "libatspi2.0-dev", "libgnatcoll-syslog2", "libgnatcoll-syslog2-dev", "libpoppler-cpp-dev"],
            "22": ["qtbase5-dev", "build-essential", "perl", "python3", "git", "ninja-build", "cmake",
                   # llvm
                   "llvm",
                   # Libxcb
                   "^libxcb.*-dev", "libx11-xcb-dev", "libgl1-mesa-dev", "libglu1-mesa-dev", "libxrender-dev",
                   "libxi-dev", "libxkbcommon-dev", "libxkbcommon-x11-dev",
                   # Wayland Client
                   "libwayland-dev",
                   # WebKit
                   "flex", "bison", "gperf", "libicu-dev", "libxslt-dev", "ruby",
                   # WebEngine
                   "libxcursor-dev", "libxcomposite-dev", "libxdamage-dev", "libxrandr-dev", "libxtst-dev",
                   "libxss-dev", "libdbus-1-dev", "libevent-dev", "libfontconfig1-dev",
                   "libcap-dev", "libpulse-dev", "libudev-dev", "libpci-dev", "libnss3-dev",
                   # Multimedia
                   "libasound2-dev", "libegl1-mesa-dev", "gperf", "bison", "nodejs", "libdrm-dev", "libasound2-dev",
                   "libgstreamer1.0-dev", "libgstreamer-plugins-base1.0-dev", "libgstreamer-plugins-good1.0-dev",
                   "libgstreamer-plugins-bad1.0-dev",
                   # 修复错误
                   "clang", "libclang-dev", "libclang-perl", "zstd", "libkrb5-dev", "libpoppler-cpp0v5",
                   "libgssapi-krb5-2", "", "freetds-dev", "libsdl2-dev", "gawk", "wayland-protocols",
                   "libbluetooth-dev", "libopenal-dev", "libflite1", "flite1-dev", "libspeechd-dev", "libdrm*",
                   "libassimp-dev", "libdlm-dev", "libdlm3", "libzstd-dev", "libvpx-dev", "libwebp-dev", "ffmpeg",
                   "libinput-dev", "minizip", "libjsoncpp-dev", "libprotobuf-dev", "liblcms2-dev", "libharfbuzz-dev",
                   "libopus-dev", "libicu-dev", "libre2-dev", "libsnappy-dev", "libminizip-dev", "libprotobuf-c-dev",
                   "protobuf-compiler", "protobuf-compiler-grpc", "libmng-dev", "libmd4c-dev", "libmd4c0", "libssl-dev",
                   "libatspi2.0-dev", "libpoppler-cpp-dev"]
        },
        "kylin" : { # 测试通过
            "v10" : ["qtbase5-dev", "build-essential", "perl", "python3", "python", "git", "ninja-build", "cmake",
                   # llvm
                   "llvm",
                   # Libxcb
                   "^libxcb.*-dev", "libx11-xcb-dev", "libgl1-mesa-dev", "libglu1-mesa-dev", "libxrender-dev",
                   "libxi-dev", "libxkbcommon-dev", "libxkbcommon-x11-dev",
                   # Wayland Client
                   "libwayland-dev",
                   # WebKit
                   "flex", "bison", "gperf", "libicu-dev", "libxslt-dev", "ruby",
                   # WebEngine
                   "libxcursor-dev", "libxcomposite-dev", "libxdamage-dev", "libxrandr-dev", "libxtst-dev",
                   "libxss-dev", "libdbus-1-dev", "libevent-dev", "libfontconfig1-dev",
                   "libcap-dev", "libpulse-dev", "libudev-dev", "libpci-dev", "libnss3-dev",
                   # Multimedia
                   "libasound2-dev", "libegl1-mesa-dev", "gperf", "bison", "nodejs", "libdrm-dev", "libasound2-dev",
                   "libgstreamer1.0-dev", "libgstreamer-plugins-base1.0-dev", "libgstreamer-plugins-good1.0-dev",
                   "libgstreamer-plugins-bad1.0-dev",
                   # 修复错误
                   "clang", "libclang-dev", "libclang-perl", "zstd", "libkrb5-dev", "libpoppler-cpp0v5",
                   "libgssapi-krb5-2", "", "freetds-dev", "libsdl2-dev", "gawk", "wayland-protocols",
                   "libbluetooth-dev", "libopenal-dev", "libflite1", "flite1-dev", "libspeechd-dev", "libdrm*",
                   "libassimp-dev", "libdlm-dev", "libdlm3", "libzstd-dev", "libvpx-dev", "libwebp-dev", "ffmpeg",
                   "libinput-dev", "minizip", "libjsoncpp-dev", "libprotobuf-dev", "liblcms2-dev", "libharfbuzz-dev",
                   "libopus-dev", "libicu-dev", "libre2-dev", "libsnappy-dev", "libminizip-dev", "libprotobuf-c-dev",
                   "protobuf-compiler", "protobuf-compiler-grpc", "libmng-dev", "libmd4c-dev", "libmd4c0", "libssl-dev",
                   "libatspi2.0-dev", "libgnatcoll-syslog2", "libgnatcoll-syslog2-dev", "libpoppler-cpp-dev"],
            "default" : ["qtbase5-dev", "build-essential", "perl", "python3", "python", "git", "ninja-build", "cmake",
                   # llvm
                   "llvm",
                   # Libxcb
                   "^libxcb.*-dev", "libx11-xcb-dev", "libgl1-mesa-dev", "libglu1-mesa-dev", "libxrender-dev",
                   "libxi-dev", "libxkbcommon-dev", "libxkbcommon-x11-dev",
                   # Wayland Client
                   "libwayland-dev",
                   # WebKit
                   "flex", "bison", "gperf", "libicu-dev", "libxslt-dev", "ruby",
                   # WebEngine
                   "libxcursor-dev", "libxcomposite-dev", "libxdamage-dev", "libxrandr-dev", "libxtst-dev",
                   "libxss-dev", "libdbus-1-dev", "libevent-dev", "libfontconfig1-dev",
                   "libcap-dev", "libpulse-dev", "libudev-dev", "libpci-dev", "libnss3-dev",
                   # Multimedia
                   "libasound2-dev", "libegl1-mesa-dev", "gperf", "bison", "nodejs", "libdrm-dev", "libasound2-dev",
                   "libgstreamer1.0-dev", "libgstreamer-plugins-base1.0-dev", "libgstreamer-plugins-good1.0-dev",
                   "libgstreamer-plugins-bad1.0-dev",
                   # 修复错误
                   "clang", "libclang-dev", "libclang-perl", "zstd", "libkrb5-dev", "libpoppler-cpp0v5",
                   "libgssapi-krb5-2", "", "freetds-dev", "libsdl2-dev", "gawk", "wayland-protocols",
                   "libbluetooth-dev", "libopenal-dev", "libflite1", "flite1-dev", "libspeechd-dev", "libdrm*",
                   "libassimp-dev", "libdlm-dev", "libdlm3", "libzstd-dev", "libvpx-dev", "libwebp-dev", "ffmpeg",
                   "libinput-dev", "minizip", "libjsoncpp-dev", "libprotobuf-dev", "liblcms2-dev", "libharfbuzz-dev",
                   "libopus-dev", "libicu-dev", "libre2-dev", "libsnappy-dev", "libminizip-dev", "libprotobuf-c-dev",
                   "protobuf-compiler", "protobuf-compiler-grpc", "libmng-dev", "libmd4c-dev", "libmd4c0", "libssl-dev",
                   "libatspi2.0-dev", "libgnatcoll-syslog2", "libgnatcoll-syslog2-dev", "libpoppler-cpp-dev"],
        },
        "default" : {
            "default": ["qtbase5-dev", "build-essential", "perl", "python3", "python", "git", "ninja-build", "cmake",
                   # llvm
                   "llvm",
                   # Libxcb
                   "^libxcb.*-dev", "libx11-xcb-dev", "libgl1-mesa-dev", "libglu1-mesa-dev", "libxrender-dev",
                   "libxi-dev", "libxkbcommon-dev", "libxkbcommon-x11-dev",
                   # Wayland Client
                   "libwayland-dev",
                   # WebKit
                   "flex", "bison", "gperf", "libicu-dev", "libxslt-dev", "ruby",
                   # WebEngine
                   "libxcursor-dev", "libxcomposite-dev", "libxdamage-dev", "libxrandr-dev", "libxtst-dev",
                   "libxss-dev", "libdbus-1-dev", "libevent-dev", "libfontconfig1-dev",
                   "libcap-dev", "libpulse-dev", "libudev-dev", "libpci-dev", "libnss3-dev",
                   # Multimedia
                   "libasound2-dev", "libegl1-mesa-dev", "gperf", "bison", "nodejs", "libdrm-dev", "libasound2-dev",
                   "libgstreamer1.0-dev", "libgstreamer-plugins-base1.0-dev", "libgstreamer-plugins-good1.0-dev",
                   "libgstreamer-plugins-bad1.0-dev",
                   # 修复错误
                   "clang", "libclang-dev", "libclang-perl", "zstd", "libkrb5-dev", "libpoppler-cpp0v5",
                   "libgssapi-krb5-2", "", "freetds-dev", "libsdl2-dev", "gawk", "wayland-protocols",
                   "libbluetooth-dev", "libopenal-dev", "libflite1", "flite1-dev", "libspeechd-dev", "libdrm*",
                   "libassimp-dev", "libdlm-dev", "libdlm3", "libzstd-dev", "libvpx-dev", "libwebp-dev", "ffmpeg",
                   "libinput-dev", "minizip", "libjsoncpp-dev", "libprotobuf-dev", "liblcms2-dev", "libharfbuzz-dev",
                   "libopus-dev", "libicu-dev", "libre2-dev", "libsnappy-dev", "libminizip-dev", "libprotobuf-c-dev",
                   "protobuf-compiler", "protobuf-compiler-grpc", "libmng-dev", "libmd4c-dev", "libmd4c0", "libssl-dev",
                   "libatspi2.0-dev", "libgnatcoll-syslog2", "libgnatcoll-syslog2-dev", "libpoppler-cpp-dev"
            ],
        }
    }

    # Binary configuration
    settings = "os", "compiler", "build_type", "arch"
    options = {"shared": [True, False], "fPIC": [True, False]}
    default_options = {"shared": False, "fPIC": True}

    # Sources are located in the same place as this recipe, copy them to the recipe
    exports_sources = "CMakeLists.txt", "src/*", "include/*"

    def config_options(self):
        '''
        针对系统，对配置命令做一些修改
        <1>conan install .
        <1>conan create .
        <1>conan build .
        <test><1>conan create .
        '''
        self.starttime = datetime.now()
        print("\033[43;34mOSmile-->", "config_options", datetime.now() - self.starttime, "\033[0m")

        # 获取系统信息
        os_name = platform.system()
        if os_name in ["Linux", "FreeBSD"]:
            import distro
            self.os_name = distro.id() or os_name
            self.os_version = distro.version(best=True).split(".")[0]
        elif os_name == "Windows" and self._conanfile.settings.get_safe("os.subsystem") == "msys2":
            self.os_name = "msys2"
            self.os_version = ""

    def configure(self):
        '''
        <2>conan install .
        <2>conan create .
        <2>conan build .
        <test><2>conan create .
        '''
        print("\033[43;34mOSmile-->", "configure", datetime.now() - self.starttime, "\033[0m")
        if self.os_name == "kylin":
            self.conf.define("tools.system.package_manager:tool", "apt-get")
        self.conf.define("tools.system.package_manager:mode", "install")
        self.conf.define("tools.system.package_manager:sudo", True)

    def layout(self):
        '''
        <3>conan install .
        <3>conan create .
        <3>conan build .
        <test><3>conan create .
        '''
        print("\033[43;34mOSmile-->", "layout", datetime.now() - self.starttime, "\033[0m")

    def system_requirements(self):
        '''
        安装需要的软件
        <4>conan install .
        <4>conan create .
        <4>conan build .
        <test><4>conan create .
        '''
        print("\033[43;34mOSmile-->", "system_requirements", datetime.now() - self.starttime, "\033[0m")
        os_name = platform.system()
        if os_name in ["Linux", "FreeBSD"]:
            import distro
            os_name = distro.id() or os_name
            os_version = distro.version(best=True).split(".")[0]
            print("OS     -->", os_name)
            print("Version-->", os_version)
            # 获取编译工具
            for tool, distros in manager_mapping.items():
                if os_name in distros:
                    break
            # 查找需要安装的包
            os_name_key = os_name if (os_name in self.packages.keys()) else "default"
            os_version_key = os_version if (os_version in self.packages[os_name_key].keys()) else "default"
            softs = self.packages.get(os_name_key).get(os_version_key)
            print("安装软件包-->", softs)
            softtool = getattr(package_manager, tool)(self)
            softtool.install(softs, update=False, check=True)
        elif os_name == "Windows" and self._conanfile.settings.get_safe("os.subsystem") == "msys2":
            os_name = "msys2"
        print(os_name)
    
    def generate(self):
        '''
        配置已经安装的软件
        <5>conan install .
        <5>conan create .
        <5>conan build .
        '''
        print("\033[43;34mOSmile-->", "generate", datetime.now() - self.starttime, "\033[0m")
        if os.path.exists(os.path.join(os.environ["HOME"], "qt-everywhere-src-5.14.2.tar.xz")):
            if not os.path.exists(os.path.join(os.environ["HOME"], "qt-everywhere-src-5.14.2")):
                self.run("tar -xvf qt-everywhere-src-5.14.2.tar.xz", cwd=os.environ["HOME"])
                self.run("mkdir build", cwd=os.path.join(os.environ["HOME"], "qt-everywhere-src-5.14.2"))
        else:
            self.run("wget https://download.qt.io/archive/qt/5.14/5.14.2/single/qt-everywhere-src-5.14.2.tar.xz", cwd=os.environ["HOME"])
            self.run("tar -xvf qt-everywhere-src-5.14.2.tar.xz", cwd=os.environ["HOME"])
            self.run("mkdir build", cwd=os.path.join(os.environ["HOME"], "qt-everywhere-src-5.14.2"))


    def build(self):
        '''
        <6>conan create .
        <6>conan build .
        '''
        print("\033[43;34mOSmile-->", "build", datetime.now() - self.starttime, "\033[0m")
        # <<< 特定系统配置 >>>
        if self.os_name == "kylin":
            # 关闭安全软件
            self.run("setstatus disable", ignore_errors=True)

        # 编译
        configstr = """
../configure \
  -prefix {}/qt-build \
  -developer-build \
  -static \
  -release \
  -confirm-license \
  -opensource \
  -nomake examples \
  -nomake tests \
  -skip qtwebengine \
  -no-pch
        """.format(os.environ["HOME"])
        self.run(configstr, cwd=os.path.join(os.environ["HOME"], "qt-everywhere-src-5.14.2", "build"))
        print("config cmd", configstr)
        self.run("make -j `nproc`", cwd=os.path.join(os.environ["HOME"], "qt-everywhere-src-5.14.2", "build"), ignore_errors=True)
        self.run("make install", cwd=os.path.join(os.environ["HOME"], "qt-everywhere-src-5.14.2", "build"), ignore_errors=True)

    def package(self):
        '''
        <7>conan create .
        '''
        print("\033[43;34mOSmile-->", "package", datetime.now() - self.starttime, "\033[0m")

    def package_info(self):
        '''
        <8>conan create .
        <test><5>conan create .
        '''
        print("\033[43;34mOSmile-->", "package_info", datetime.now() - self.starttime, "\033[0m")
        self.cpp_info.libs = ["QTBuild"]

